<?php

declare (strict_types=1);

namespace app\api\service\user;



use app\api\model\Goods;
use app\api\model\user\PointsLog;

use app\api\service\User;
use app\common\enum\PointsType;
use app\common\model\user\Postslikelog;
use app\common\service\BaseService;
use app\api\model\user\Posts as PostsModel;
use cores\exception\BaseException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\facade\Cache;
use think\facade\Db;
use think\helper\Str;

/**
 * 服务类:帖子服务类
 * Class Avatar
 * @package app\api\service\user
 */
class Posts extends BaseService
{
    const max_upload_image = 9;

    /**帖子列表
     * @param $params
     * @return array
     * @throws BaseException
     * @throws DbException
     */
    public function getIndex($params):array
    {
        $user_id = 0;
        $condition = [];
        if(!empty($params['me'])){
            $user_id = User::getCurrentLoginUserId();
            $condition[] = ['user_id','=',$user_id];
        }else{
            $condition[] = ['status','=',1];
        }
        return (new PostsModel())::with(['user' => function($query){
            $query->withField(['user_id','avatar_url','nick_name','username']);
        }])
            ->field('id,title,user_id,cover_url,goods_id,like_num,status')
            ->where($condition)
            ->paginate()
            ->each(function (&$item) use ($user_id){
                $is_like = 0;
                if($user_id > 0){
                    $is_like = $this->isLike($item['id'],$user_id);
                }
                $item['is_like'] = $is_like;
            })
            ->toArray();
    }

    /**用户是否点赞
     * @param $posts_id
     * @param $user_id
     * @return int
     */
    public function isLike($posts_id,$user_id):int
    {
        $condition = [
            ['user_id','=',$user_id],
            ['posts_id','=',$posts_id]
        ];
        $like_log = (new Postslikelog())->where($condition)->find();
        $is_like = 0;
        if($like_log){
            $is_like = 1;
        }
        return $is_like;
    }


    /**发布
     * @param $params
     * @return array
     * @throws BaseException
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function publish($params):array
    {
        if($params['type'] == 1){
            //todo 图片最多传9张
            $image_urls = explode(',',$params['image_url']);
            if(count($image_urls) > self::max_upload_image){
                throwError('最多只能上传9张');
            }
            $cover_url = $image_urls[0];
        }else{
            //获取视频第一帧
            $cover_url = '';
        }
        $user_id = User::getCurrentLoginUserId();
        $postModel = new PostsModel();
        //todo 事务处理
        $postModel->startTrans();
        try {
            $posts = (new PostsModel())::create([
                'type' => $params['type'],
                'user_id' => $user_id,
                'title' => $params['title'],
                'description' => $params['description'] ?? '',
                'cover_url' => $cover_url,
                'image_url' => $params['image_url'] ?? '',
                'video_url' => $params['video_url'] ?? '',
                'goods_id' => $params['relation_goods_id'] ?? '',
                'activity_id' => $params['relation_activity_id'] ?? ''
            ]);
            if(!$posts->id){
                throwError('insert posts error');
            }

            $postModel->commit();

            return [
                'lottery_code' => []
            ];
        }catch (\Exception $exception){
            $postModel->rollback();
            throwError($exception->getMessage());
        }

    }

    /**点赞、取消点赞
     * @param $params
     * @return bool
     */
    public function like($params):bool
    {
        $user_id = User::getCurrentLoginUserId();
        $post_model = new PostsModel();
        $posts =  $post_model
            ->where('id',$params['id'])
            ->find();
        if(!$posts){
            throwError('帖子不存在');
        }
        if($posts->status != 1){
            throwError('只能点赞审核通过的帖子');
        }

        $condition = [
            ['user_id','=',$user_id],
            ['posts_id','=',$params['id']]
        ];
        $post_model->startTrans();
        try {
            if($params['type'] == 1){
                //查看点赞记录
                $like_log = (new Postslikelog())->where($condition)->lock(true)->find();
                if($like_log){
                    throw new Exception('已点赞,请勿重复点赞');
                }
                $like_log = (new Postslikelog())::create([
                    'posts_id' => $params['id'],
                    'user_id' => $user_id,
                ]);
                if(!$like_log->id){
                    throw new Exception('insert posts_like_log error');
                }
                $posts->like_num = Db::raw('like_num+1');
            }else{
                $like_log = (new Postslikelog())->where($condition)->lock(true)->find();
                if(!$like_log){
                    throw new Exception('未点赞,无需取消点赞');
                }
                (new Postslikelog())->where($condition)->delete();
                $posts->like_num = Db::raw('like_num-1');
            }
            $posts->save();
            $post_model->commit();
            return true;
        }catch (\Exception $exception){
            $post_model->rollback();
            throwError($exception->getMessage());
        }
    }

    /**详情
     * @return array
     */
    public function getDetail($id):array
    {
        $user_id = User::getCurrentLoginUserId();
        $posts =  (new PostsModel())::with(['user' => function($query){
            $query->withField(['user_id','avatar_url','nick_name','username']);
        }])
            ->where('id','=',$id)
            ->find();
        if(!$posts) throwError('帖子不存在');

        $posts->relation_goods_info = new \stdClass();
        $posts->is_like = $this->isLike($posts->id,$user_id);
        return $posts->toArray();

    }

    /**排行榜
     * @param $token
     * @return array
     * @throws BaseException
     */
    public function rankList($token):array
    {
        $points_log = (new PointsLog())
            ->with(['user' => function($query){
                $query->withField(['user_id','nick_name','avatar_url']);
            }])
            ->field('scene,user_id,-sum(value) as points,`describe`,remark')
            ->where('scene','IN',[PointsType::GIFT_EXCHANGE,PointsType::PARTICIPANT_EXCHANGE])
            ->group('user_id')
            ->order('points','DESC')
            ->select();
        
        if(!$points_log->isEmpty()){
            $points_log = $points_log->toArray();
        }
        $points_log = array_slice($points_log,0,100);
        $me_rank = 0;
        $tmp = [];
        foreach ($points_log as $k => &$datum){
            $datum['points'] = (int)$datum['points'];
            $datum['rank'] = $k + 1;
            if($token){
                $user_id = Cache::get($token)['user']['user_id'] ?? 0;
                if($datum['user_id'] == $user_id){
                    $me_rank = $k + 1;
                }
            }
            $tmp[] = array_merge($datum['user'],[
                'rank' => $datum['rank'],
                'points' => $datum['points']
            ]);
        }
       // dd($tmp);
        $tmp = array_values($tmp);
        $me_info = new \stdClass();
        if($me_rank > 0){
            $me_info = $tmp[$me_rank - 1];
        }
        return [
            'rank_list' => $tmp,
            'me_info' => $me_info
        ];
    }
}